package com.leenmvc.core.dao.sqlServer.wrapper;

import com.leenmvc.core.annotation.PrimaryKey;
import com.leenmvc.core.annotation.TableField;
import com.leenmvc.core.base.BaseEntity;
import com.leenmvc.core.dao.communal.Wrapper;
import com.leenmvc.core.utils.ClassUtil;
import com.leenmvc.core.utils.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SqlServerUpdateWrapper extends Wrapper {

    /**
     * Set值集合
     */
    private List<String> sets = new ArrayList<>();

    public SqlServerUpdateWrapper() {}

    /**
     * update tb_school set name=? where id=?
     *
     * @return
     */
    @Override
    public String getSql() {
        String tableName = BaseEntity.getTableName(cls);
        this.sql.append("update ").append(tableName).append(" set ");
        this.sql.append(StringUtils.join(sets, ","));
        if(where.length() > 0) {
            this.sql.append(" where " + where);
        }
        return this.sql.toString();
    }

    public <T> SqlServerUpdateWrapper(T t) {
        update(t);
    }

    /**
     * 从sets集合中移除
     *
     * @param set
     * @return
     */
    public SqlServerUpdateWrapper removeSet(String set) {
        for(int i = 0; i < sets.size(); i++) {
            String k = sets.get(i);
            if(k.startsWith(set)) {
                paramList.remove(i);
                sets.remove(i);
                break;
            }
        }
        return this;
    }

    /**
     * 添加sets集合中
     *
     * @param setKey
     * @return
     */
    public SqlServerUpdateWrapper addSet(String setKey, Object value) {
        String column = BaseEntity.humpLine(setKey);
        for(int i = 0; i < sets.size(); i++) {
            String k = sets.get(i);
            if(k.startsWith(column)) {
                sets.remove(i);
                paramList.remove(i);
                break;
            }
        }
        sets.add(column + " = ? ");
        paramList.add(value);
        return this;
    }



    public <T> SqlServerUpdateWrapper update(T t) {
        if(t == null) return null;
        Class<?> cls = t.getClass();
        this.setCls(cls);

        for (Field field : cls.getDeclaredFields()) {
            PrimaryKey annotation = field.getAnnotation(PrimaryKey.class);
            TableField tableField = field.getAnnotation(TableField.class);
            String columnName = BaseEntity.humpLine(field);
            if(annotation != null) continue;
            if(tableField != null && !tableField.value()) continue;
            sets.add(columnName + " = ?");
            try {
                Object obj = ClassUtil.getGetMethod(field).invoke(t, null);
                this.paramList.add(obj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

        this.where.append(BaseEntity.getPrimaryFieldName(cls) + " = ?");
        this.paramList.add(ClassUtil.getPrimaryFieldValue(t));
        return this;
    }

    public SqlServerUpdateWrapper(Class<?> cls, Map<String, Object> params) {
        update(cls, params);
    }

    public SqlServerUpdateWrapper update(Class<?> cls, Map<String, Object> params) {
        this.cls = cls;
        String tableName = BaseEntity.getTableName(cls);
        List<String> sets = new ArrayList<String>();
        for(String key: params.keySet()) {
            sets.add(BaseEntity.humpLine(key) + " = ?");
            this.paramList.add(params.get(key));
        }
        return this;
    }

    @Override
    public SqlServerUpdateWrapper and() {
        this.where.append(" and ");
        return this;
    }

    @Override
    public Wrapper joinOne(String field) {
        return this;
    }

    @Override
    public Wrapper joinMul(String field) {
        return this;
    }

    @Override
    public Wrapper joinField(String field) {
        return this;
    }

    public SqlServerUpdateWrapper and(String field, Object value) {
        this.where.append(" and ").append(field + " = ?");
        paramList.add(value);
        conditons.add(BaseEntity.humpLine(field) + " = ?");
        return this;
    }

    // or 连接符
    public SqlServerUpdateWrapper or() {
        this.where.append(" or ");
        return this;
    }

    // 使用
    public SqlServerUpdateWrapper linkOr() {
        int index = this.where.lastIndexOf(conditons.get(conditons.size() - 1), this.where.length() - 1);
        this.where.insert(index, "(");
        this.where.append(" or)");
        return this;
    }

    // 如果传参数那么默认就是用等号连接
    public SqlServerUpdateWrapper or(String field, Object value) {
        this.where.append(" or ").append(field + " = ?");
        paramList.add(value);
        conditons.add(BaseEntity.humpLine(field) + " = ?");
        return this;
    }

    public SqlServerUpdateWrapper count(Class<?> cls) {
        this.cls = cls;
        this.sql.append("select count(1) from ").append(BaseEntity.getTableName(cls));
        return this;
    }

    // order by
    public SqlServerUpdateWrapper orderBy(String field, String desc) {
        this.orderBy.append(field).append(" ").append(desc);
        return this;
    }

    /**
     * 排除某个字段
     *
     * @param fields
     * @return
     */
    public SqlServerUpdateWrapper decField(String... fields) {
        setAnd();
        for(String field: fields) {
            field = BaseEntity.humpLine(field);
            this.columns.remove(field);
        }
        return this;
    }

    /**
     * 只显示某些字段
     *
     * @param fields
     * @return
     */
    public SqlServerUpdateWrapper incField(String... fields) {
        setAnd();
        this.columns.clear();
        for(String field: fields) {
            field = BaseEntity.humpLine(field);
            this.columns.add(field);
        }
        return this;
    }

    /**
     * 限制条数
     *
     * @param pageInfo
     * @return
     */
    public SqlServerUpdateWrapper limit(Integer...pageInfo) {
        return this;
    }

    /**
     * 等于
     */
    public SqlServerUpdateWrapper eq(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.eq(field, value);
        return this;
    }

    /**
     * 不等于
     *
     * @param field
     * @param value
     * @return
     */
    public SqlServerUpdateWrapper uEq(String field, Object value) {
        super.uEq(field, value);
        return this;
    }

    /**
     * 右边随意
     *
     * @param field
     * @param value
     * @return
     */
    public SqlServerUpdateWrapper likeR(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.likeR(field, value);
        return this;
    }

    /**
     * 左边随意
     *
     * @param field
     * @param value
     * @return
     */
    public SqlServerUpdateWrapper likeL(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.likeL(field, value);
        return this;
    }

    /**
     * 全like
     *
     * @param field
     * @param value
     * @return
     */
    public SqlServerUpdateWrapper like(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.like(field, value);
        return this;
    }

    /**
     * 根据数组中
     *
     * @param field
     * @param ins
     * @return
     */
    public SqlServerUpdateWrapper in(String field, Object[] ins) {
        if (ins == null) return this;
        super.in(field, ins);
        return this;
    }

    public <T> SqlServerUpdateWrapper in(String field, List<T> ins) {
        return this.in(field, ins.toArray());
    }

    // between
    public SqlServerUpdateWrapper between(String field, Object start, Object end) {
        setAnd();
        super.between(field, start, end);
        return this;
    }

    // <
    public SqlServerUpdateWrapper lt(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.lt(field, value);
        return this;
    }

    // >
    public SqlServerUpdateWrapper gt(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.gt(field, value);
        return this;
    }

    // >=
    public SqlServerUpdateWrapper ge(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.ge(field, value);
        return this;
    }

    // <=
    public SqlServerUpdateWrapper le(String field, Object value) {
        if (StringUtils.isEmpty(value)) return this;
        super.le(field, value);
        return this;
    }

    // is null
    public SqlServerUpdateWrapper isNull(String field) {
        setAnd();
        super.isNull(field);
        return this;
    }

    // is not null
    public SqlServerUpdateWrapper isNotNull(String field) {
        setAnd();
        super.isNotNull(field);
        return this;
    }

    /**
     * 将hashMap转成SqlServerUpdateWrapper
     * like关键字 规则如下（前缀）：
     * LL_  左像（%在左边）
     * RL_  右像 (%在右边)
     * AL_  全像 (%在两边)  AL_username   %leen%
     * orderBY关键字规则如下 （前缀）：
     * OB_  排序的字段  value值为DESC 或 ESC    OB_createTime   DESC
     * page, pageSize 特殊字保留字 （只做分页功能）
     *
     * @return
     */
    public SqlServerUpdateWrapper mapToWrapper(Map<String, Object> params) {
        super.mapToWrapper(params);
        return this;
    }
    @Override
    public void copy(Wrapper wrapper)  {
        super.copy(wrapper);
    }
}
